#include <netdb.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <time.h>

#include "ourhdr.h"

#define LISTENNQ      20

typedef struct sockaddr SA;

static int Socket(int family, int type, int protocol)
{
    int fd;
    if ((fd = socket(family, type, protocol)) < 0) {
        err_sys("socket error");
    }

    return fd;
}

static int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
    int ret;
    if ((ret = accept(sockfd, addr, addrlen)) < 0) {
        err_sys("accept error");
    }

    return ret;
}

static int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    int ret;
    if ((ret = bind(sockfd, addr, addrlen)) < 0) {
        err_sys("bind error");
    }

    return ret;
}

static int Listen(int sockfd, int backlog)
{
    int ret;
    if ((ret = listen(sockfd, backlog)) < 0) {
        err_sys("listen error");
    }

    return ret;
}

static ssize_t Write(int fd, const void *buf, size_t count)
{
    ssize_t ret;
    if ((ret = write(fd, buf, count)) < 0) {
        err_sys("write error");
    }

    return ret;
}

static int Close(int fd) 
{
    int ret;
    if ((ret = close(fd)) < 0) {
        err_sys("close error");
    }

    return ret;
}


int main() 
{
    int listenfd, connfd;
    struct sockaddr_in servaddr;
    char buff[MAXLINE];
    time_t ticks;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    /* 服务器有多少个网络接口, 服务器进程就能在任意网络接口上接受客户连接 */
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(13); /* daytime server */

    Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
    
    Listen(listenfd, LISTENNQ);

    while (1) {
        connfd = Accept(listenfd, (SA *)NULL, NULL);

        ticks = time (NULL);
        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
        Write(connfd, buff, strlen(buff));

        Close(connfd);
    }

    return 0;
}

